package com.ruoyi.algorithm.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.algorithm.entity.*;
import com.ruoyi.algorithm.model.*;
import com.ruoyi.algorithm.repository.*;
import com.ruoyi.algorithm.service.AlgorithmService;
import com.ruoyi.algorithm.util.ReflectionUtil;
import com.beihu.sightplus.common.authorization.service.UserAuthorization;
import com.beihu.sightplus.common.response.PageResult;
import com.beihu.sightplus.common.response.PageUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class AlgorithmServiceImpl implements AlgorithmService {
    @Autowired
    private AlgorithmRepository algorithmRepository;

    @Autowired
    private AlgorithmHistoryRepository algorithmHistoryRepository;

    @Autowired
    private VideoAnalyseConfigRepository videoAnalyseConfigRepository;

    @Autowired
    private PictureAnalyseConfigRepository pictureAnalyseConfigRepository;

    @Autowired
    private FeatureConfigRepository featureConfigRepository;

    /**
     * 新增算法
     */
    public void add(AlgorithmModel algorithmModel) {
        // 解析出Algorithm对象，图片分析配置对象，特征分析配置对象，视频分析配置对象
        Algorithm algorithm = new Algorithm();
        BeanUtils.copyProperties(algorithmModel, algorithm);

        VideoAnalyseConfig videoAnalyseConfig = algorithmModel.getVideoAnalyseConfig();
        // 将视频分析配置数据，保存到数据库中
        videoAnalyseConfig.setCreateTime(new Date()); // 创建时间
        videoAnalyseConfig.setCreateUser(UserAuthorization.getUserAuthorization().getId()); // 创建人
        videoAnalyseConfig.setUpdateTime(new Date()); // 修改时间
        videoAnalyseConfig.setDelFlag("0"); // 删除标志（0未删除；1已删除）
        videoAnalyseConfigRepository.save(videoAnalyseConfig);
        algorithm.setVideoAnalyseConfigId(videoAnalyseConfig.getId());

        PictureAnalyseConfig pictureAnalyseConfig = algorithmModel.getPictureAnalyseConfig();
        // 将图片分析配置数据，保存到数据库中
        pictureAnalyseConfig.setCreateTime(new Date()); // 创建时间
        pictureAnalyseConfig.setCreateUser(UserAuthorization.getUserAuthorization().getId()); // 创建人
        pictureAnalyseConfig.setUpdateTime(new Date()); // 更新时间
        pictureAnalyseConfig.setDelFlag("0"); // 删除标志（0未删除；1已删除）
        pictureAnalyseConfigRepository.save(pictureAnalyseConfig);
        algorithm.setPictureAnalyseConfigId(pictureAnalyseConfig.getId());

        // 将特征分析配置数据，保存到数据库中
        FeatureConfig featureConfig = algorithmModel.getFeatureConfig();
        featureConfig.setCreateTime(new Date()); // 创建时间
        featureConfig.setCreateUser(UserAuthorization.getUserAuthorization().getId()); // 创建人
        featureConfig.setUpdateTime(new Date()); // 更新时间
        featureConfig.setDelFlag("0"); // 删除标志（0未删除；1已删除）
        featureConfigRepository.save(featureConfig);
        algorithm.setFeatureConfigId(featureConfig.getId());


        algorithm.setIsOnline("0"); // 在线标志
        algorithm.setCreateTime(new Date()); // 创建时间
        algorithm.setCreateUser(UserAuthorization.getUserAuthorization().getId()); // 创建人
        algorithm.setUpdateTime(new Date()); // 更新时间
        algorithm.setDelFlag("0"); // 逻辑删除标志(0：未删除，1：已删除)

        AlgorithmHistory algorithmHistory = new AlgorithmHistory();
        BeanUtils.copyProperties(algorithm, algorithmHistory);

        algorithmRepository.save(algorithm);
        algorithmHistory.setId(null);
        algorithmHistory.setAlgorithmId(algorithm.getId());
        algorithmHistoryRepository.save(algorithmHistory);
    }

    /**
     * 修改，当算子发生变化时，需要往算法历史表中添加一条新的数据，否则，算法表和算法历史表的数据，均进行修改操作
     */
    public void update(AlgorithmModel algorithmModel) {
        Algorithm algorithm = new Algorithm();
        BeanUtils.copyProperties(algorithmModel, algorithm);

        // 到数据库中查询原算法
        Algorithm orgAlgorithm = algorithmRepository.getById(algorithm.getId());

        // 更新特征分析配置数据
        FeatureConfig featureConfig = algorithmModel.getFeatureConfig();
        featureConfig.setId(orgAlgorithm.getFeatureConfigId());
        featureConfig.setUpdateTime(new Date());
        featureConfig.setUpdateUser(UserAuthorization.getUserAuthorization().getId());
        featureConfigRepository.updateById(featureConfig);

        // 更新图片分析配置数据
        PictureAnalyseConfig pictureAnalyseConfig = algorithmModel.getPictureAnalyseConfig();
        pictureAnalyseConfig.setId(orgAlgorithm.getPictureAnalyseConfigId());
        pictureAnalyseConfig.setUpdateTime(new Date());
        pictureAnalyseConfig.setUpdateUser(UserAuthorization.getUserAuthorization().getId());
        pictureAnalyseConfigRepository.updateById(pictureAnalyseConfig);

        // 更新视频分析配置数据
        VideoAnalyseConfig videoAnalyseConfig = algorithmModel.getVideoAnalyseConfig();
        videoAnalyseConfig.setId(orgAlgorithm.getVideoAnalyseConfigId());
        videoAnalyseConfig.setUpdateTime(new Date());
        videoAnalyseConfig.setUpdateUser(UserAuthorization.getUserAuthorization().getId());
        videoAnalyseConfigRepository.updateById(videoAnalyseConfig);

        // 获取算子信息
        Long orgOperatorId = orgAlgorithm.getOperatorId();

        // 判断算子信息是否发生了变化
        Long operatorId = algorithm.getOperatorId();

        // 若发生变化且在历史算法表中，不存在该算法和算子数据，则修改算法表信息，并向算法历史表中添加一条新的数据
        algorithm.setUpdateTime(new Date());
        algorithm.setUpdateUser(UserAuthorization.getUserAuthorization().getId());
        algorithmRepository.updateById(algorithm);

        AlgorithmHistory algorithmHistory = new AlgorithmHistory();
        BeanUtils.copyProperties(algorithm, algorithmHistory);
        algorithmHistory.setAlgorithmId(algorithm.getId());

        AlgorithmHistory history = algorithmHistoryRepository.getByAlgorithmIdAndOperatorId(orgAlgorithm.getId(), operatorId);
        if (orgOperatorId.longValue() != operatorId.longValue() && history == null){
            algorithmHistory.setIsOnline("0"); // 在线标志
            algorithmHistory.setCreateTime(new Date()); // 创建时间
            algorithmHistory.setCreateUser(UserAuthorization.getUserAuthorization().getId()); // 创建人
            algorithmHistory.setUpdateTime(new Date()); // 更新时间
            algorithmHistory.setVideoAnalyseConfigId(orgAlgorithm.getVideoAnalyseConfigId()); // 视频解析配置
            algorithmHistory.setPictureAnalyseConfigId(orgAlgorithm.getPictureAnalyseConfigId()); // 图片解析配置
            algorithmHistory.setFeatureConfigId(orgAlgorithm.getFeatureConfigId()); // 特征解析配置
            algorithmHistory.setDelFlag("0"); //删除标记

            algorithmHistoryRepository.save(algorithmHistory);
        } else {
            // 若没有发生变化，则修改算法表和算法历史表的数据
            AlgorithmHistory orgAlgorithmHistory = algorithmHistoryRepository.getLatestByAlgorithmId(algorithm.getId());
            algorithmHistory.setId(orgAlgorithmHistory.getId());
            algorithmHistory.setUpdateTime(new Date());
            algorithmHistory.setUpdateUser(UserAuthorization.getUserAuthorization().getId());

            algorithmHistoryRepository.updateByAlgorithmIdAndOperatorId(algorithm.getId(), algorithm.getOperatorId(), algorithmHistory);
        }
    }

    /**
     * 删除
     */
    public void delete(Long algorithmId) {
        Algorithm algorithm = new Algorithm();
        algorithm.setId(algorithmId);
        algorithm.setDelFlag("1");
        algorithmRepository.updateById(algorithm);
    }

    /**
     * 算法上下线
     */
    public void setOnlineState(AlgorithmOnLineStateModel algorithmOnLineStateModel) {
        Algorithm algorithm = new Algorithm();
        algorithm.setId(algorithmOnLineStateModel.getAlgorithmId());
        algorithm.setIsOnline(algorithmOnLineStateModel.getOptionType());
        algorithmRepository.updateById(algorithm);
    }

    /**
     * 查询算法详情信息
     */
    public AlgorithmModel detail(Long algorithmId) {
        // 查询算法的基础信息
        Algorithm algorithm = algorithmRepository.getById(algorithmId);

        // 查询算法对应的图片解析配置数据
        PictureAnalyseConfig pictureAnalyseConfig = pictureAnalyseConfigRepository.getById(algorithm.getPictureAnalyseConfigId());

        // 查询算法对应的视频解析配置数据
        VideoAnalyseConfig videoAnalyseConfig = videoAnalyseConfigRepository.getById(algorithm.getVideoAnalyseConfigId());

        // 查询算法对应的特征解析配置数据
        FeatureConfig featureConfig = featureConfigRepository.getById(algorithm.getFeatureConfigId());

        AlgorithmModel algorithmModel = new AlgorithmModel();
        BeanUtils.copyProperties(algorithm, algorithmModel);
        algorithmModel.setPictureAnalyseConfig(pictureAnalyseConfig);
        algorithmModel.setVideoAnalyseConfig(videoAnalyseConfig);
        algorithmModel.setFeatureConfig(featureConfig);

        return algorithmModel;
    }

    /**
     * 根据算法Id和算子Id,查询历史算法信息
     */
    public AlgorithmHistoryModel getAlgorithmHistoryByAlgorithmIdAndOperatorId(Long algorithmId, Long operatorId) {
        // 查询历史算法基础信息
        AlgorithmHistory history = algorithmHistoryRepository.getByAlgorithmIdAndOperatorId(algorithmId, operatorId);

        // 查询算法对应的图片解析配置数据
        PictureAnalyseConfig pictureAnalyseConfig = pictureAnalyseConfigRepository.getById(history.getPictureAnalyseConfigId());

        // 查询算法对应的视频解析配置数据
        VideoAnalyseConfig videoAnalyseConfig = videoAnalyseConfigRepository.getById(history.getVideoAnalyseConfigId());

        // 查询算法对应的特征解析配置数据
        FeatureConfig featureConfig = featureConfigRepository.getById(history.getFeatureConfigId());

        AlgorithmHistoryModel algorithmHistoryModel = new AlgorithmHistoryModel();
        BeanUtils.copyProperties(history, algorithmHistoryModel);

        algorithmHistoryModel.setFeatureConfig(featureConfig);
        algorithmHistoryModel.setPictureAnalyseConfig(pictureAnalyseConfig);
        algorithmHistoryModel.setVideoAnalyseConfig(videoAnalyseConfig);

        return algorithmHistoryModel;
    }

    /**
     * 数据查询
     * @Param orderAttr 排序的字段
     * @Param orderType 排序的方式，Asc升序，Desc降序
     * @Param current 当前页码
     * @Param size 每页展示的条数
     * @Param algorithmListModel 具体的查询条件
     */
    public PageResult listByPage(String orderAttr, String orderType, Long current, Long size, AlgorithmListModel algorithmListModel) {
        // 处理动态查询提交，提取出，有值且值不为null的数据
        Map map = JSONObject.parseObject(JSON.toJSONString(algorithmListModel), Map.class);
        Set keySet = map.keySet();

        List<Map<String, Object>> conditionList = new ArrayList<>();

        List<Class<?>> clazzList = new ArrayList<>();
        clazzList.add(AlgorithmListModel.class);
        for (Object keyObject : keySet) {
            String key = keyObject.toString();
            String conditionKey = ReflectionUtil.getTableFieldValue(clazzList, key);
            if (conditionKey == null) {
                continue;
            }

            Map<String, Object> conditionMap = new HashMap<>();
            conditionMap.put("conditionKey", conditionKey);
            conditionMap.put("conditionValue", map.get(key));

            // 从属性上获取匹配符号
            String matchType = ReflectionUtil.getTableFieldMatchType(algorithmListModel.getClass(), key);

            if (matchType.contains("LIKE")) {
                conditionMap.put("conditionMatchType", 1);
            } else {
                conditionMap.put("conditionMatchType", 0);
            }

            conditionList.add(conditionMap);
        }

        Page<AlgorithmListModel> page = algorithmRepository.listByPage(conditionList, ReflectionUtil.getTableFieldValue(clazzList, orderAttr), orderType, current, size);

        return PageUtils.getPageResult(page);
    }
}
